import 'dart:developer';
import 'dart:io';

import 'package:common_utils/common_utils.dart';
import 'package:fate_blind_box/config/app_utils.dart';
import 'package:fate_blind_box/config/event_bus.dart';
import 'package:fate_blind_box/config/event_keys.dart';
import 'package:fate_blind_box/model/chat_friend_message_entity.dart';
import 'package:fate_blind_box/model/group_intro_entity.dart';
import 'package:fate_blind_box/network/Api.dart';
import 'package:fate_blind_box/utils/loading.dart';
import 'package:fate_blind_box/utils/snack_bar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:im_flutter_sdk/im_flutter_sdk.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:video_player/video_player.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart'
    hide ImageFormat;

import 'state.dart';

class GroupChatLogic extends GetxController {
  final GroupChatState state = GroupChatState();

  @override
  void onInit() {
    super.onInit();
    // TODO: implement onInit
    if (Get.arguments != null) {
      state.groupId = Get.arguments['id'];
      state.owner = Get.arguments['owner'];
      state.title.value = Get.arguments['title'];
      state.avatarUrl.value = Get.arguments['avatarUrl'];
    }
    onRefresh();
    addEventBus();
    _addEventHandler();
  }

  /// 获取群聊信息
  _getUserinfo() async {
    if (state.groupId.isEmpty) return;
    final res = await Api.getInstance().getGroupInfo(state.groupId);
    if (res != null && ObjectUtil.isNotEmpty(res['data'])) {
      state.model.value = GroupIntroEntity.fromJson(res['data']);
      state.model.refresh();
    } else {
      EasyLoading.showToast('群简介异常');
    }
  }

  onRefresh() async {
    state.messageList.clear();
    state.userInfoList.clear();
    EasyLoading.show();

    /// 获取当前会话，有的地方进来没有会话的，所以如果没有需要创建，比如群列表
    state.conversation = await EMClient.getInstance.chatManager.getConversation(
      state.groupId,
      type: EMConversationType.GroupChat,
      createIfNeed: true,
    );

    /// 从本地数据库 获取消息列表
    List<EMMessage>? list = await state.conversation?.loadMessages(
      startMsgId: '',
      loadCount: 20,
      direction: EMSearchDirection.Up,
    );

    /// 判断是否有更多
    if (list != null && list.length == 20) {
      state.hasMore.value = true;
    } else {
      state.hasMore.value = false;
    }
    if (list == null) {
      return;
    }
    var teamp = <EMUserInfo>[];
    for (int i = 0; i < list.length; i++) {
      int index = teamp.indexWhere((element) => element.userId == list[i].from);
      if (index == -1) {
        Map<String, EMUserInfo> userInfo = await EMClient
            .getInstance.userInfoManager
            .fetchUserInfoById([list[i].from ?? '']);
        teamp.add(userInfo.values.first);
      } else {
        teamp.add(teamp[index]);
      }
    }
    EasyLoading.dismiss();
    state.userInfoList.addAll(teamp.reversed);
    state.messageList.addAll(list.reversed);
    state.messageList.refresh();
  }

  onLoading() async {
    /// 从本地数据库 获取消息列表
    List<EMMessage>? list = await state.conversation?.loadMessages(
      startMsgId: state.messageList.last.msgId,
      loadCount: 20,
      direction: EMSearchDirection.Up,
    );
    state.refreshController.loadComplete();
    if (list?.length == 20) {
      state.hasMore.value = true;
    } else {
      state.hasMore.value = false;
    }
    if (list == null) {
      return;
    }
    var teamp = <EMUserInfo>[];
    for (int i = 0; i < list.length; i++) {
      int index = state.userInfoList
          .indexWhere((element) => element.userId == list[i].from);
      int teampIndex =
          teamp.indexWhere((element) => element.userId == list[i].from);
      if (index == -1 && teampIndex == -1) {
        Map<String, EMUserInfo> userInfo = await EMClient
            .getInstance.userInfoManager
            .fetchUserInfoById([list[i].from ?? '']);
        teamp.add(userInfo.values.first);
      } else {
        teamp.add(index == -1 ? teamp[teampIndex] : state.userInfoList[index]);
      }
    }
    state.userInfoList.addAll(teamp.reversed);
    state.messageList.addAll(list.reversed);
    state.messageList.refresh();
  }

  /// 获取好友资料信息
  getFriendMessage(String from) async {
    final res = await Api.getInstance().getUserInfo(from);
    if (res['code'] == 0 && res['data'] != null) {
      var model = ChatFriendMessageEntity.fromJson(res['data']);
      state.locInfoList.add(model);
      state.locInfoList.refresh();
    }
  }

  /// 发送消息成功消息监听
  addEventBus() {
    EventBus.instance.addListener(EventKeys.chatUpdateAudioMessage,
        (arg) async {
      if (arg.runtimeType == EMMessage) {
        EMMessage message = arg;
        Map<String, EMUserInfo> userInfo = await EMClient
            .getInstance.userInfoManager
            .fetchUserInfoById([message.from ?? '']);
        // await getFriendMessage(message.from ?? '');
        state.userInfoList.insertAll(0, userInfo.values.toList().reversed);
        state.messageList.insert(0, message);
        state.messageList.refresh();
      }
    });
  }

  _addEventHandler() {
    /// 添加消息接收器监听
    EMClient.getInstance.chatManager.addEventHandler(
      state.tag,
      EMChatEventHandler(
        onMessagesReceived: (messages) async {
          getConversation(message: messages);
        },
      ),
    );

    // 群消息发送状态监听
    EMClient.getInstance.chatManager.addMessageEvent(
        state.tag,
        ChatMessageEvent(
          onSuccess: (msgId, msg) {
            // state.conversation?.updateMessage(msg);
            replaceMessage(msgId: msgId, message: msg);
          },
          onProgress: (msgId, progress) {
            log('消息发送进度==$msgId==$progress');
            EMMessage? message = getCurrentMessage(msgId);
            if (message != null) {
              message.attributes = {'progress': progress};
              state.messageList.refresh();
            }
          },
          onError: (msgId, msg, error) {},
        ));

    /// 群组状态监听，当前监听了群成员变化
    EMClient.getInstance.groupManager.addEventHandler(
        state.tag,
        EMGroupEventHandler(
            onMemberJoinedFromGroup: (String groupId, String member) =>
                insertCustomMessage(groupId, member)));
  }

  /// 根据消息Id 检查消息列表中是否有当前消息
  EMMessage? getCurrentMessage(String msgId) {
    return state.messageList.firstWhere((element) => element.msgId == msgId);
  }

  /// 根据消息id 获取当前消息-为了替换本地消息
  /// msgId 旧消息id
  /// message  新消息
  /// 然后用新消息去替换旧消息，然后刷新页面即可
  replaceMessage({required String msgId, required EMMessage message}) async {
    final index =
        state.messageList.indexWhere((element) => element.msgId == msgId);
    if (index != -1) {
      state.messageList[index] = message;
      state.messageList.refresh();
      await EMClient.getInstance.chatManager.importMessages([message]);
    }
  }

  /// 根据会话id 获取当前会话
  getConversation({required List<EMMessage> message}) async {
    await EMClient.getInstance.chatManager.importMessages(message);
    for (int i = 0; i < message.length; i++) {
      await state.conversation?.markMessageAsRead(message[i].msgId);
      if (message[i].conversationId == state.groupId) {
        Map<String, EMUserInfo> userInfo = await EMClient
            .getInstance.userInfoManager
            .fetchUserInfoById([message[i].from ?? '']);
        // await getFriendMessage(message[i].from ?? '');
        state.userInfoList.insertAll(0, userInfo.values.toList().reversed);
        state.messageList.insert(0, message[i]);
        state.messageList.refresh();
        // 将当前消息标记为已读
      }
    }
  }

  /// 插入自定义消息
  insertCustomMessage(String groupId, String member) async {
    await _getUserinfo();
    Api.getInstance().getUserInfo(member)?.then((value) {
      if (value != null && value['code'] == 0) {
        var message = EMMessage.createCustomSendMessage(
          targetId: groupId,
          event: 'addGroup',
          params: {
            "id": '${value['data']['id']}',
            "user_id": member, // 加入者id
            'user_name': '${value['data']['nickName']}',
            "from_type": "通过扫一扫", // 通过什么方式加入
            "from_id": "", // 邀请人id
          },
          chatType: ChatType.GroupChat,
        );
        EMClient.getInstance.chatManager
            .importMessages([message]).then((value) => onRefresh());
      }
    });
    return;
  }

  /// 最新一条消息
  EMMessage? get lastMessage {
    if (state.messageList.isNotEmpty) {
      return state.messageList.first;
    } else {
      return null;
    }
  }

  // 判断是相机还是相册
  checkAvatar(String type) {
    checkPhotoPermission(type);
    if (type == '图片') {
    } else {
      // 视频
    }
  }

  /// 检查相机权限
  checkPermissionStatus() async {
    PermissionStatus cameraStatus = await Permission.camera.status;
    if (!cameraStatus.isGranted) {
      // 相机权限未授权
      if (await Permission.camera.request().isGranted) {
        // 用户已授权相机权限
      } else {
        // 用户拒绝了相机权限
        await openAppSettings();
      }
    } else {
      // 相机权限已授权
      if (!kIsWeb) {
        loading(() async {
          final picker = ImagePicker();
          final pickerFile =
              await picker.pickImage(source: ImageSource.gallery);
          if (pickerFile != null) {
            //裁剪后图片的路径
            String filepath = pickerFile.path;
            if (filepath.toString().isEmpty) return;
            EMMessage message = EMMessage.createImageSendMessage(
              targetId: state.groupId,
              filePath: filepath.toString(),
              chatType: ChatType.Chat,
            );
            EMClient.getInstance.chatManager.sendMessage(message);
          }
        });
      }
    }
  }

  /// 检测相册权限
  checkPhotoPermission(String type) async {
    var status = await AppUtils.permissionPhotos();
    if (status) {
      selectPhoto(type);
    } else {
      Permission permission = await AppUtils.getPhotoPermission();
      if (await permission.request().isGranted) {
        // 用户已授权相册权限
        selectPhoto(type);
      } else {
        // 用户拒绝了相册权限
        await openAppSettings();
      }
    }
  }

  /// 根据权限跳转
  selectPhoto(String type) {
    if (type == '图片') {
      _pickImageFromPhoto();
    } else {
      _pickVideoFromPhoto();
    }
  }

  /// 从相册选择视频
  _pickVideoFromPhoto() async {
    FilterOptionGroup optionGroup = FilterOptionGroup()
      ..containsLivePhotos = false;
    final List<AssetEntity>? entities = await AssetPicker.pickAssets(
        Get.context!,
        pickerConfig: AssetPickerConfig(
            maxAssets: 1,
            requestType: RequestType.video,
            filterOptions: optionGroup));
    if (entities == null) return;
    for (AssetEntity entity in entities) {
      File? file = await entity.file;
      if (file == null) return;
      VideoPlayerController controller = VideoPlayerController.file(file);
      controller.initialize().then((value) async {
        var urlPath = await VideoThumbnail.thumbnailFile(
          video: file.path,
          imageFormat: ImageFormat.PNG,
          maxWidth: 260,
          quality: 80,
        );
        if (urlPath == null) return;
        _createVideoMessage(controller, file, urlPath);
        // 释放资源
        controller.dispose();
      });
    }
  }

  /// 从相册选择照片
  _pickImageFromPhoto() async {
    final List<AssetEntity>? entity = await AssetPicker.pickAssets(Get.context!,
        pickerConfig: const AssetPickerConfig(
          maxAssets: 9,
          requestType: RequestType.image,
        ));
    if (entity == null) return;
    for (AssetEntity entity in entity) {
      File? imgFile = await entity.file;
      if (imgFile == null) return;
      final size = await AppUtils.getImageSize(imgFile);
      _sendImageMessage(
        imgFile.path,
        size.width,
        size.height,
      );
    }
  }

  /// 拍摄
  cameraAction(BuildContext context) async {
    final AssetEntity? entity = await CameraPicker.pickFromCamera(
      Get.context!,
      pickerConfig: const CameraPickerConfig(
          enableRecording: true,
          maximumRecordingDuration: Duration(seconds: 30)),
    );
    if (entity == null) return;
    File? imgFile = await entity.file;
    if (imgFile == null) return;
    if (entity.duration > 0) {
      VideoPlayerController controller = VideoPlayerController.file(imgFile);
      controller.initialize().then((value) async {
        var urlPath = await VideoThumbnail.thumbnailFile(
          video: imgFile.path,
          imageFormat: ImageFormat.PNG,
          maxWidth: 260,
          quality: 80,
        );
        if (urlPath == null) return;
        _createVideoMessage(controller, imgFile, urlPath);
        // 释放资源
        controller.dispose();
      });
    } else {
      final size = await AppUtils.getImageSize(imgFile);
      _sendImageMessage(
        imgFile.path,
        size.width,
        size.height,
      );
    }
  }

  /// 创建视频消息
  _createVideoMessage(
      VideoPlayerController controller, File file, String urlPath) {
    EMMessage message = EMMessage.createVideoSendMessage(
      targetId: state.groupId,
      filePath: file.path,
      duration: controller.value.duration.inSeconds,
      width: controller.value.size.width.toDouble(),
      height: controller.value.size.height.toDouble(),
      thumbnailLocalPath: urlPath,
      chatType: ChatType.GroupChat,
    );
    _sendVideoMessage(message);
  }

  /// 发送图片
  _sendImageMessage(String filePath, int width, int height) async {
    EMMessage message = EMMessage.createImageSendMessage(
      targetId: state.groupId,
      filePath: filePath.toString(),
      width: width.toDouble(),
      height: height.toDouble(),
      chatType: ChatType.GroupChat,
    );
    bool status = await EMClient.getInstance.isConnected();
    if (status) {
      EMClient.getInstance.chatManager.sendMessage(message).then((value) {
        EventBus.instance
            .commit(eventName: EventKeys.chatUpdateAudioMessage, data: message);
      });
    } else {
      ThemeSnackBar.show(Get.context!, '已断线,请重新登陆~');
      FocusScope.of(Get.context!).unfocus();
    }
  }

  /// 发送消息
  _sendVideoMessage(EMMessage message) async {
    bool status = await EMClient.getInstance.isConnected();
    if (status) {
      EMClient.getInstance.chatManager.sendMessage(message).then((value) {
        EventBus.instance
            .commit(eventName: EventKeys.chatUpdateAudioMessage, data: message);
      });
    } else {
      ThemeSnackBar.show(Get.context!, '已断线,请重新登陆~');
      FocusScope.of(Get.context!).unfocus();
    }
  }

  // 隐藏键盘
  hideKeyboard() {
    if (state.focusNode.hasFocus) {
      state.focusNode.unfocus();
    }
    Get.back(result: lastMessage);
  }

  @override
  void onClose() {
    // TODO: implement onClose
    super.onClose();
    EventBus.instance
        .removeListener(eventName: EventKeys.chatUpdateAudioMessage);
    EMClient.getInstance.chatManager.removeEventHandler(state.tag);
    EMClient.getInstance.chatManager.removeMessageEvent(state.tag);
    EMClient.getInstance.groupManager.removeEventHandler(state.tag);
    state.scrollController.dispose();
  }
}
